firebaseてめえ
概要
iOSアプリをAppTransferすると、firebase cloud messagingの通知が最低10日の間不完全な状態になる。有り体に言うと死ぬ。
これは開発者側からは何もできることはない。10日間絶え間なく12の型を繋げていれば(サポートとやり取りしていれば)いつの間にか解決する。おクソでございますわね。
Transferすると何が起きるのか
fcmに登録する要素として、APNs関連のAuthorization KeyとTeamIDの2つがあり、これらがTransfer前とTransfer後で当然変わる。
そしてTransferに際して、これらのfcmのパラメータを変更したが最後、いや変更するしかないんだが、
・旧来のTeamIDのユーザーへの通知が全て死ぬ
・新規のTeamIDのユーザーへの通知がだんだんと有効になる
ということが起きる。
具体例としては、
Aさん、Bさんという2名のiOSAppユーザーがいた時、AppTransferの瞬間からAさん、Bさんへのpushは404エラーを返すようになり、
Aさんは2日後にはpushが届くようになり、Bさんはなんと10日後にpushが届くようになる。
何故こうなるのか
一部、Firebaseの内部IDに対してのみ俺の憶測が入る。他は観測した。
firebase cloud messagingのiOS関連のアカウントは、2020/07現在、次のような形式でAPNsとの連携を実装している。
FirebasePushUserID(仮) - firebase push token
\_ APNs token
FirebasePushUserID(FPUID) は適当に外部から想像する代物なんだけど、pushに関して、firebaseが管理するこのようなデータ構造がユーザー単位で存在すると思いねえ。
firebase push tokenは7dayくらいの寿命を持ち、例えばUnity firebase cloud messaging SDKは、1W(7day)に一度、firebaseから新しいfirebase push token(FPToken)を受け取る。
これにより、FPUIDに紐づくFPTokenが更新される。端末とかは変わってないので、APNs tokenは変わらない、みたいな状態が起きる。
FirebasePushUserID(仮) - firebase push token <- こいつが更新される
\_ APNs token <- このへんは変わらない
App側はそのFPTokenを自社のWebサーバとかに送付して、以降push通知を流したいタイミングで、次のような通信を行う。
Webサーバ(FPToken使用) -> fcm(紐づくAPNs使用) -> ユーザーデバイスに通知が届く
これが正常系。まあそれはいい。
でねーこれねー、Transferがあったタイミング以降で、FPTokenが更新されても、一定期間、Webサーバ-fcm間で404エラーが出るんだよね。
いやFPTokenの寿命が1Wって言ってるから、そりゃ更新されるタイミングはTransferから最大1Wなのでは?って思うじゃん? 違うんだよ。
fcmは、Transfer以後にたまたま寿命を迎えたFPTokenが更新されても、FPTokenを強制的に更新しても、10日間くらいの間は、404エラーになるようなFPTokenを返してくるんだよね。
は?っていうね。 更新したのに404なのかよ。
次のようなパターンがあるのを確認している。
case 1. Transfer以降で、App起動時に1Wに一度、fcmから新しいFPTokenを取得できるが、そのFPTokenは404エラーになる
case 2. Transfer以降で、Appのpush通知設定を変更することでfcmから新しいFPTokenを取得できるが、そのFPTokenは404エラーになる
case 3. Transfer以降で、Appを新規インストール/再インストール(削除してから再インストール!)した場合、それ以降に取得できるFPTokenは正常な動作をする(が、どうやって促すんだよ、push届かねえんだっつうの)
case 4. Transfer以降で、Appを更新した場合、それ以降に取得できるFPTokenは正常な動作をする(らしい、未確認、いやでもお前どうやって促すんだよ、push届かねえんだっつうの)
というような感じになっている。case 1, 2, 3, 4全部に問題がある。なんだこれ地獄かね。
Transferから10日間が過ぎたあたりで、FPTokenが更新された以降で404が出なくなる。404が出ない状態のFPTokenが配布され始めるんだ。
だんだんとpush失敗のログから404が減っていき、ついにはTransfer前と同等に戻る。
これは繰り返しになるが、FPTokenの更新頻度は関係ない。真っ当な、404エラーにならないFPTokenがfirebaseから確実に取得できるのが、Transferから10日以降なのだ。
もちろんばらつきはある。このばらつきによって、Transferから1度目のFPToken更新で404にならないFPTokenを引けるユーザもいれば、そうではなくハズレFPTokenを得るユーザーもいる。
firebase側もこの状態になったときに何かできるかというと何もできない。開発者も何もできないしfirebase側も何もできない。最悪の体験だった。
firebaseよ、こうなるのを知っとけ。ドキュメントに書いとけ。OK? みたいな。ふふ。
エラーが最悪
このcase 1,2で発生する404エラーは、通常のfcmが返してくる「お前が指定した端末はそんざいしないゾ☆」エラーと見分けがつかない。
突然404エラーが増えて見えるわけで、は? ってなるが、まあ、何もできない。
どう回避すればいいのか
Transfer時にfcmを使わない。
自前でAPNs tokenを保持しておき、Transferから10dayか2W(14day)経過するまでは、自前でAPNs tokenを使ってpushする。
もしこうなったときに、やった方がいいこと
Transfer後、即iOSアプリの審査を登録しても2-3日、それが全ユーザーに知れ渡るまでに4-5日、その間は無防備睡眠状態で殴られ続ける。
pushは届かない。お知らせもユーザーがアプリを起動するまで無意味。唯一アプリ入れ直しだけが意味を成すが、いや、ユーザーにそれをさせちゃダメでしょ。正気を疑う。
こうなってしまった場合にできることはない。何をしても無駄。
こうなる前に、やった方がいいこと
Firebase Cloud MessagingのUnity SDKは、まあiOS SDKもだが、APNsを取得するルートをmethod swizzlingによってAppから奪うことで動作している。
これさーマジでさー、この構造やめてくんねーかなー、せめて一瞬でいいからUnityとかiOSにも取得チャンスくれや、改造すんぞ。
ということで改造しましょう。APNsを取り戻しつつfcmにもFPTokenを作ってもらう。